package com.smedi.ismedi.inmail.core.port.adapter.restful;

import com.smedi.ismedi.authority.starter.util.VerifyHelper;
import com.smedi.ismedi.inmail.api.dto.request.*;
import com.smedi.ismedi.inmail.api.dto.response.ProcessTaskResponse;
import com.smedi.ismedi.inmail.api.feign.RemoteProcessFeignApi;
import com.smedi.ismedi.inmail.core.application.command.*;
import com.smedi.ismedi.inmail.core.application.service.ProcessApplicationService;
import com.smedi.ismedi.inmail.core.domain.aggregatemodel.ProcessTask;
import com.smedi.ismedi.inmail.core.port.adapter.convert.AdapterConverter;
import com.smedi.ismedi.web.starter.common.ResponseData;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

import static com.smedi.ismedi.inmail.api.constant.ConstantField.FINISHED;

@AllArgsConstructor
@RestController
public class ProcessController implements RemoteProcessFeignApi {

    private final ProcessApplicationService processApplicationService;

    private final AdapterConverter adapterConverter;

    @Override
    public ResponseData<Boolean> deployProcessDefinition(MultipartFile processPerformFile) throws IOException {
        processApplicationService.deployProcessDefinition(processPerformFile);
        return new ResponseData<>().success(true);
    }

    @Override
    public ResponseData<ProcessTaskResponse> startProcessInstance(ProcessInstanceStartRequest processInstanceStartRequest) {
        ProcessInstanceStartCommand processInstanceStartCommand = adapterConverter.processInstanceStartRequestToProcessInstanceStartCommand(processInstanceStartRequest);
        ProcessTask processTask = processApplicationService.startProcessInstance(processInstanceStartCommand);
        ProcessTaskResponse processTaskResponse = adapterConverter.processTaskToProcessTaskResponse(processTask);
        return new ResponseData<>().success(processTaskResponse);
    }

    @Override
    public ResponseData<ProcessTaskResponse> completeProcessTask(ProcessTaskCompleteRequest processTaskCompleteRequest) {
        ProcessTaskCompleteCommand processTaskCompleteCommand = adapterConverter.processTaskCompleteRequestToProcessTaskCompleteCommand(processTaskCompleteRequest);
        List<ProcessTask> processTasks = processApplicationService.completeProcessTask(processTaskCompleteCommand);
        if (VerifyHelper.isNotAvailable(processTasks)) {
            return new ResponseData<>().success(ProcessTaskResponse.builder().status(FINISHED).build());
        }
        ProcessTaskResponse processTaskResponse = adapterConverter.processTaskToProcessTaskResponse(processTasks.get(0));
        return new ResponseData<>().success(processTaskResponse);
    }

    @Override
    public ResponseData<List<ProcessTaskResponse>> completeProcessTask2(ProcessTaskCompleteRequest processTaskCompleteRequest) {
        ProcessTaskCompleteCommand processTaskCompleteCommand = adapterConverter.processTaskCompleteRequestToProcessTaskCompleteCommand(processTaskCompleteRequest);
        List<ProcessTask> processTasks = processApplicationService.completeProcessTask(processTaskCompleteCommand);
        List<ProcessTaskResponse> processTaskResponses = adapterConverter.processTaskToProcessTaskResponse(processTasks);
        return new ResponseData<>().success(processTaskResponses);
    }

    @Override
    public ResponseData<List<ProcessTaskResponse>> getProcessTaskList(ProcessTaskListRequest processTaskListRequest) {
        ProcessTaskListCommand processTaskListCommand = adapterConverter.processTaskListRequestToProcessTaskListCommand(processTaskListRequest);
        List<ProcessTask> processTasks = processApplicationService.getProcessTaskList(processTaskListCommand);
        List<ProcessTaskResponse> processTaskResponses = adapterConverter.processTaskToProcessTaskResponse(processTasks);
        return new ResponseData<>().success(processTaskResponses);
    }

    @Override
    public ResponseData<Boolean> closeProcessInstance(ProcessInstanceCloseRequest processInstanceCloseRequest) {
        ProcessInstanceCloseCommand processInstanceCloseCommand = adapterConverter.processInstanceCloseRequestToProcessInstanceCloseCommand(processInstanceCloseRequest);
        processApplicationService.closeProcessInstance(processInstanceCloseCommand);
        return new ResponseData<>().success(true);
    }

    @Override
    public ResponseData<ProcessTaskResponse> cancelProcessTask(ProcessTaskCancelRequest processTaskCancelRequest) {
        ProcessTaskCancelCommand processTaskCancelCommand = adapterConverter.processTaskCancelRequestToProcessTaskCancelCommand(processTaskCancelRequest);
        ProcessTask processTask = processApplicationService.cancelProcessTask(processTaskCancelCommand).get(0);
        ProcessTaskResponse processTaskResponse = adapterConverter.processTaskToProcessTaskResponse(processTask);
        return new ResponseData<>().success(processTaskResponse);
    }

    @Override
    public ResponseData<List<ProcessTaskResponse>> cancelProcessTask2(ProcessTaskCancelRequest processTaskCancelRequest) {
        ProcessTaskCancelCommand processTaskCancelCommand = adapterConverter.processTaskCancelRequestToProcessTaskCancelCommand(processTaskCancelRequest);
        List<ProcessTask> processTasks = processApplicationService.cancelProcessTask(processTaskCancelCommand);
        List<ProcessTaskResponse> processTaskResponses = adapterConverter.processTaskToProcessTaskResponse(processTasks);
        return new ResponseData<>().success(processTaskResponses);
    }
}
